home *** CD-ROM | disk | FTP | other *** search
- /* MYLIB.C Generic Library Functions */
-
- /* Copyright (c) Gregg Jennings 1989-1994 */
-
- #include <stdio.h>
- #include <ctype.h>
- #include <conio.h>
- #include <string.h>
- #include <dos.h>
-
- #include "mylib.h"
-
- #define _tohex(c) ( (c<='9') ? (c-'0') : (c-'7') )
-
- #define ischar(c) ( c != 0 && c != 7 && c != 8 && c != 9 && c != 10 && \
- c != 13 && c != 27 && c != 255 )
-
- /*
- Convert two ASCII hex-valid chars to one hex number.
- A '0' and a 'd' returns the value 0x0d. The second
- argument can be a '\r'.
-
- No checking for validity.
-
- ver 1.1 9/91 fixed ascii mask error, added _tohex() macro
- ver 1.0 12/90
- */
- unsigned char hexbyte(register int a,register int b)
- {
- a=toupper(a);
- b=toupper(b);
-
- if (b=='\r') { /* swap if '\r' */
- b=a;
- a='0';
- }
- return((unsigned char)((_tohex(a)*16)+_tohex(b)));
- }
- /*
- * Display a number to the console with leading zeros or space
- * and a certain length, and any base from 2 to 36.
- *
- * pn print int number
- * pln print long number
- *
- * Returns: number of digits.
- *
- * ver 1.0 9/91 eliminated all but 2 divisions pln(), 3 in pn()
- * ver 0.1 12/90
- */
-
- int pn(unsigned int n, int base)
- {
- int r=1;
- int i;
-
- if (n/base)
- r+=pn(n/base,base);
- i=n%base;
- conout((i>9) ? i+'A'-10 : i+'0');
- return(r);
- }
-
- int pln(unsigned long n, int base)
- {
- int r=1;
- long l;
- int i;
-
- if (((l=n/(long)base))>0)
- r+=pln(l,base);
- i=(int)(n%(long)base);
- if (i>9)
- conout(i+'A'-10);
- else
- conout(i+'0');
- return(r);
- }
-
- /*
- * Display a number to the console with leading zeros or space
- * and a certain length, and any base from 2 to 36.
- *
- * pnlz print number leading zero
- * pnls print number leading space
- * plnlz print long number leading zero
- * plnls print long number leading space
- *
- * ver 1.0 9/91
- */
-
- void pnlz(unsigned int n, unsigned int length, int base)
- {
- register int t;
-
- for (t=length-getlen(n,base);t>0;t--)
- conout('0');
- pn(n,base);
- }
-
- void pnls(unsigned int n, unsigned int length, int base)
- {
- register int t;
-
- for (t=length-getlen(n,base);t>0;t--)
- conout(' ');
- pn(n,base);
- }
-
- void plnlz(unsigned long n, unsigned int length, int base)
- {
- register int i;
-
- for (i=length-getlength(n,base);i>0;i--)
- conout('0');
- pln(n,base);
- }
-
- void plnls(unsigned long n, unsigned int length, int base)
- {
- register int i;
-
- for (i=length-getlength(n,base);i>0;i--)
- conout(' ');
- pln(n,base);
- }
-
- /*
- * get the display length (number of digits) of a
- * number, i.e. 100 dec returns 3, 64 hex (100 dec)
- * returns 2
- */
-
- int getlen(register unsigned int n, register int base)
- {
- int j;
-
- for (j=1;n>=(unsigned int)base;n/=base,++j)
- ;
- return(j);
- }
- /*
- Get length of number.
- Pass: long number, int base (1 to 26).
- Returns: the number of digits the number needs to be displayed.
-
- ver 0.1 12/90
- ver 0.2 3/91 changed to long
- */
-
- int getlength(unsigned long l, int base)
- {
- register int r;
-
- for (r=1;l>=(unsigned long)base;l/=(long)base,++r)
- ;
- return(r);
- }
-
- /*
- Convert a string containing escape sequences
- to their correct values.
-
- Returns: the converted string's length.
-
- ver 1.1 9/91 changed \x to fixed 2 chars (\x0d not \xd)
- ver 1.0 3/91
- ver 0.1 12/90
- */
-
- int convert(register char *a)
- {
- register char *s;
- int j;
-
- s=a;
- for (j=0;*a!='\0';a++,j++) {
- if (*a=='\\') {
- switch (*++a) {
- case 'x':
- *(s+j)=hexbyte(*(a+1),*(a+2));
- a+=2;
- break;
- case 'a':
- *(s+j)='\a';
- break;
- case 'b':
- *(s+j)='\b';
- break;
- case 'f':
- *(s+j)='\f';
- break;
- case 'n':
- *(s+j)='\n';
- break;
- case 'r':
- *(s+j)='\r';
- break;
- case 't':
- *(s+j)='\t';
- break;
- case 'v':
- *(s+j)='\v';
- break;
- case '0':
- *(s+j)='\0';
- break;
- case '\\':
- *(s+j)='\\';
- break;
- default:
- break;
- }
- }
- else
- *(s+j)=*a;
- }
- *(s+j)='\0';
- a=s;
- return(j);
- }
- /*
- Display the current directory in a combination DIR /P /W
- format.
-
- ver 0.3 9/91 call to lpd()
- ver 0.2 3/91
- */
-
- void dir(void)
- {
- int files=0;
- struct find_t file;
- long fsize = 0L;
- struct diskfree_t ds;
- long dsize;
- extern unsigned int disk;
- extern unsigned avail_clusters;
- extern unsigned secs_cluster;
- extern unsigned sec_size;
-
- send('\n');
- if (_dos_findfirst("*.*",0x3f,&file)==0)
- {
- do
- {
- pname(file.name);
- print(" ");
- if (file.attrib&_A_SUBDIR)
- print(" <DIR>");
- else if (file.attrib&_A_VOLID)
- print(" <VOL>");
- else
- {
- plnls(file.size,7,10);
- fsize+=file.size;
- }
- ++files;
- print((files%3==0) ? "\n" : " ");
- if (files%60==0)
- pause();
- } while (_dos_findnext(&file)==0); /* while being found*/
- }
- if (files==0)
- print("no files");
- send('\n');
- if (avail_clusters==0)
- {
- _dos_getdiskfree(disk,&ds);
- dsize = ((long)ds.avail_clusters*(long)ds.sectors_per_cluster*(long)ds.bytes_per_sector);
- }
- else
- dsize = ((long)avail_clusters*(long)secs_cluster*(long)sec_size);
- printf(" file space %ld, disk space %ld\n",fsize,dsize);
- }
-
- /*
- Displays the filename returned by _dos_findnext() in a nice
- format.
-
- ver 0.2 3/91
- */
-
- void pname(char *s)
- {
- register int i;
- register int j;
-
- i=0;
- conout(' ');
- while (s[i]!='.' && s[i]!='\0')
- conout(s[i++]);
- j= (s[i]!='\0') ? i+1 : i;
- while (i++<8)
- conout(' ');
- if (s[j])
- conout('.');
- else
- conout(' ');
- while (i++<=11)
- conout( (s[j]=='\0') ? ' ' : s[j++]);
- }
-
- /*
- Modified K&R index() for a non-null terminated string.
-
- ver 0.1 12/90
- */
-
- search(unsigned char *s,unsigned char *t,unsigned int size,unsigned int len)
- {
- unsigned int i;
- register unsigned int j,k;
-
- if (size>len) {
- size-=len;
- for (i=0;i<=size;i++) {
- for (j=i,k=0;k<len && s[j]==t[k];j++,k++)
- continue;
- if (k==len)
- return(i);
- }
- }
- return(-1);
- }
-
- /* case-insensitive search 11-93 */
-
- isearch(unsigned char *s,unsigned char *t,unsigned int size,unsigned int len)
- {
- unsigned int i;
- register unsigned int j,k;
-
- if (size > len)
- {
- size-=len;
- for (i=0;i <= size;i++)
- {
- for (j=i,k=0;k<len && (s[j]==t[k] || toupper(s[j]) == toupper(t[k]));j++,k++)
- continue;
- if (k==len)
- return(i);
- }
- }
- return(-1);
- }
- /*
- Display a string with a question mark and return TRUE if a 'y'
- is found on console, else return FALSE.
-
- mode: 0 no mov/clr
- (bit) 1 cursor back to "Yes/No "
- 2 cursor back to arg s
- 4 clreol if "Yes"
-
- ver 0.3 9/93 added cursor, clreol
- ver 0.2 3/91
- ver 0.1 12/91
- */
-
- int getver(register char *s,int mode)
- {
- int c;
-
- if (mode&2) /* mov arg */
- savecursor();
- print(s);
- conout('?');
- conout(' ');
- if (mode&1) /* mov yn */
- savecursor();
- c=input();
- if (tolower(c)!='y')
- {
- print("No ");
- c = 0;
- if (mode)
- restcursor();
- }
- else
- {
- print("Yes");
- c = 1;
- if (mode)
- restcursor();
- if (mode&4)
- clreol();
- }
- return c;
- }
- /*
- Get number from console by calling getstr() and sscanf().
- Handles base of 10 or 16 only.
-
- Pass: long maximum number, pointer to number, int base (1 to 26).
-
- Returns: TRUE (1) if number okay
- FALSE (0) if no entry
- ERROR (-1) if too big a number
- ABORT (-2) on ESC or ^C
-
- Calls: getstr()
-
- ver 0.1 12/90
- ver 1.0 2/91 pass pointer
- */
- int getnumber(unsigned long max, void *num, int base)
- {
- char tmpstr[11]; /* longest number is unsigned long of 10 digits */
- char format[4]; /* format string for sscanf() */
- int i;
- unsigned long l;
- long *pl=num; /* make sure we have enough space */
-
- i=0;
- format[i++]='%';
- format[i++]='l';
- (base==10) ? (format[i]='d') : (format[i]='x');
- format[++i]='\0';
- i=getstr(tmpstr,getlength(max,base),(base==10)?_DIGIT:_HEX);
- if (i<0)
- {
- if (i==ERROR)
- i=0;
- return(i);
- }
- sscanf(tmpstr,format,&l);
- if (l>max)
- return(ERROR);
- *pl=l;
- return(TRUE);
- }
-
- int getnum(unsigned int max, unsigned *num, int base)
- {
- char tmpstr[7]; /* longest number is unsigned 6 digits */
- char format[3]; /* format string for sscanf() */
- int i;
- unsigned int u;
- unsigned int *pu=num; /* make sure we have enough space */
-
- i=0;
- format[i++]='%';
- (base==10) ? (format[i]='u') : (format[i]='x');
- format[++i]='\0';
- i=getstr(tmpstr,getlen(max,base),(base==10)?_DIGIT:_HEX);
- if (i<0)
- {
- if (i==ERROR)
- i=0;
- return(i);
- }
- sscanf(tmpstr,format,&u);
- if (u>max)
- return(ERROR);
- *pu=u;
- return(TRUE);
- }
-
- /*
- Get a string from console, masking to hex or decimal
- numbers only or punctuation, depending on the mask value,
- with CP/M editing control keys.
-
- Pass: pointer to string, int max length, int mask.
-
- Returns: -2 on ESC or ^C
- -1 on no input ('\r')
- -3 on no input (space or ',')
-
- Uses: put(), bdos(), send() and <ctype.h>.
-
- ver 1.0 9/93 added -3 return
- ver 0.1 12/90
- */
-
- int getstr(char *s,unsigned int len,int mask)
- {
- register unsigned int i;
- register int c;
-
- savecursor();
- for (i=0;i<len;)
- {
- switch (c=input())
- {
- case 8:
- if (i)
- {
- conout(c);
- conout(' ');
- conout(c);
- --i;
- }
- break;
- case 0x15: /* ^U to delete */
- if (i)
- {
- restcursor();
- clreol();
- i=0;
- }
- break;
- case 0x1b:
- case 3: /* ESC to abort */
- s[0]='\0';
- return(ABORT);
- break;
- case '\r': /* end of input */
- case ' ':
- case ',':
- break;
- default:
- if (mask==_DIGIT && (!isdigit(c)))
- continue;
- if (mask==_HEX && (!isxdigit(c)))
- continue;
- conout(c); /* save and echo numbers */
- s[i++]=(char)c;
- continue;
- break;
- }
- if (c==' ' || c==',' || c=='\r')
- break;
- }
- s[i]='\0';
- if (!i)
- return (c=='\r') ? ERROR : -3;
- return(i);
- }
-
- /*
- Edit a buffer, in a debugger type format. Asks for the starting
- point of the editing. Checks for end of buffer and wraps around.
- Allows hex and ASCII substitutions, jumps to a buffer location, and
- hex number fills.
-
- A complicated, horrible looking function but it works.
-
- Uses getnumber(), bdos(), hexbyte(), dispval() and <ctype.h>.
-
- GAJ initial
- GAJ added ASCII subs
- GAJ 1-8-89 added ^x
- GAJ 1-9-89 added \c
- GAJ 3-8-89 updated help
- GAJ 12-8-90 cleaned up
- */
- change(register unsigned char *buffer,unsigned int bufend,int base)
- {
- unsigned int a;
- unsigned int b;
- int c; /* chars gotten from the console */
- unsigned int n,i; /* x = buffer index, n = getval, i = general purpose*/
- register unsigned int x;
- int inquote,ad; /* for inputing a string */
- int l;
- char t[66];
-
- if (bufend<=0)
- return(0);
- n=0;
- if (getnum(bufend,&n,base)==ABORT)
- return(0);
- ad=getlen(bufend,base);
- x=n;
- inquote=FALSE;
- send('\n');
- for (;;) {
- c=buffer[x]; /* display address, byte, and ASCII */
- dispval(x,ad,base,c);
- if (!inquote)
- a=input()&0xff;
-
- if (a=='\\') { /* search */
- conout(a); /* echo */
- a=input()&0xff; /* get */
- if (a=='^') { /* control */
- conout(a); /* echo */
- b=input()&0xff; /* get */
- if (isalpha(b)) { /* letter */
- a=toupper(b); /* upper */
- conout(a); /* echo */
- c=(a-'@'); /* convert */
- }
- else continue; /* else redo */
- }
- else if (a=='\'') { /* get ASCII */
- conout(a);
- b=input()&0xff;
- if (b>=' ') { /* is okay? */
- conout(b); /* echo */
- c=b; /* set */
- }
- else continue; /* else redo */
- }
- else if (isxdigit(a)) {
- conout(a);
- b=input()&0xff; /* get second */
- if (isxdigit(b) || b=='\r') {
- if (b!='\r')
- conout(b);
- c=hexbyte(a,b); /* convert */
- }
- else continue;
- } /* search loop */
- i=x; /* save place */
- while (c!=(int)buffer[++x]) {
- if (x==bufend) /* wrap at end */
- x=0;
- if (x==i) /* stop */
- break;
- }
- continue;
- }
- else if (a=='\"') { /* get string */
- conout(a);
- inquote=FALSE; /* bool for continueing */
- if ((l=getstr(t,63,_PUNCT))>0) {
- for (i=0;i<(unsigned)l;i++) { /* copy string */
- buffer[x++]=t[i];
- if (x==bufend) /* wrap around */
- x=0;
- }
- }
- else continue;
- if (l==63)
- inquote=TRUE;
- continue;
- }
- else if (a=='^') { /* get control */
- conout(a);
- b=input()&0xff;
- if (isalpha(b)) {
- b=toupper(b);
- conout(b);
- buffer[x]=(char)(b-'@');
- }
- else continue;
- }
- else if (a=='\'') { /* get ASCII */
- conout(a);
- b=input()&0xff;
- if (b>=' ') { /* is okay? */
- conout(b); /* yes, display and set */
- buffer[x]=(char)b;
- }
- else continue;
- }
- else if (a=='=') { /* jump to addr */
- conout(a);
- if (getnum(bufend,&n,base)<1)
- continue;
- if (n>bufend)
- continue;
- x=n;
- continue;
- }
- else if (a=='\r' || a==' ') /* go to next */
- ;
- else if (a=='\t') { /* goto 0000: */
- x = 0;
- continue;
- }
- else if (a=='.' || a==ESC) /* exit */
- break;
- else if (a=='\b') { /* go to previous */
- if (--x == 0xffff) {
- x=(bufend-1); /* if end, wrap */
- send('\n');
- }
- continue;
- }
- else if (a=='/' || a=='?') { /* dislpay help */
- print("\n\n\txx enter hex value xx");
- print("\n\t'c enter ASCII char c");
- print("\n\t^c enter control char c");
- print("\n\t\"s enter string s");
- print("\n\tCR/SP next location");
- print("\n\tBS previous location");
- print("\n\tTAB goto location 00");
- print("\n\t=n goto location n");
- print("\n\t\\xx goto hex value xx");
- print("\n\t\\\'c goto char c");
- print("\n\t\\^c goto control char c");
- print("\n\t-x1,x2 write x1, x2 times");
- print("\n\t+x1,x2 replace all x1, with x2");
- print("\n\t.|ESC end\n");
- continue;
- }
- else if (a=='-') { /* fill */
- conout(a);
- if (getnum(0xff,&a,16)<1)
- continue;
- conout(',');
- if (getnum(bufend,&b,16)<1) /* get second byte */
- continue;
- n=x; /* save position */
- for (i=0;i<b;i++) { /* all okay, fill it */
- buffer[x]=(char)a;
- if (++x==bufend) /* wrap around at end */
- x=0;
- }
- x=n; /* restore position */
- continue;
- }
- else if (a=='+') { /* fill */
- conout(a);
- if (getnum(0xff,&a,16)<1) /* get first byte */
- continue;
- conout(',');
- if (getnum(0xff,&b,16)<1) /* get second byte */
- continue;
- if (a==b)
- continue;
- for (i=0;i<bufend;i++) { /* all okay, fill it */
- if (buffer[i]==(unsigned char)a)
- buffer[i]=(unsigned char)b;
- }
- continue;
- }
- else if (isxdigit(a)) {
- conout(a);
- b=input()&0xff; /* get second */
- if (isxdigit(b) || b=='\r') {
- if (b!='\r')
- conout(b);
- buffer[x]=hexbyte(a,b); /* convert */
- }
- else continue;
- }
- else continue;
- if (++x==bufend) { /* increment pointer, wrap if end */
- x=0;
- send('\n');
- }
- }
- send('\n');
- return(1);
- }
-
- void dispval(int x, int len, int base, int c)
- {
- send('\n');
- pnlz(x,len,base);
- conout(':');
- conout(' ');
- pnlz(c,2,16);
- conout(' ');
- if (isprint(c)) {
- conout('\'');
- conout(c);
- conout('\'');
- }
- else if (iscntrl(c)) {
- conout('^');
- conout(c+'@');
- conout(' ');
- }
- else
- put(3,' ');
- put(2,' ');
- }
-
- /*
- Display data in a HEX-ASCII format, starting at buf, ending at
- bufend. Returns the number of bytes displayed. bufend _must_
- be a multiple of 128
-
- unsigned char *buffer; - array of data
- unsigned int bfptr; - index into array
- unsigned int bufend; - size of array
- unsigned int len; - number of bytes to display
- int base;
- */
- int dump(unsigned char *buffer,unsigned int bfptr,unsigned int bufend,unsigned int len,int base)
- {
- register unsigned int c;
- unsigned int l,n;
- register int b;
-
- if (bfptr>bufend)
- bfptr=0;
- if (len>bufend)
- len=bufend;
- n=bfptr;
- for (l=0;l<len;l+=16) {
- send('\n');
- pnlz(bfptr,getlen(bufend,base),base);
- conout(':');
- conout(' ');
- for (b=0; b<16; b++) { /* of 16 bytes each */
- c=buffer[bfptr];
- conout( ((c>>=4) > 9) ? (c+0x57) : (c+'0'));
- c=buffer[bfptr];
- conout( ((c&=0xf) > 9) ? (c+0x57) : (c+'0'));
- conout(' ');
- if (++bfptr==bufend) {
- bfptr=0;
- break;
- }
- }
- for (b=0; b<16; b++) { /* in hex and ascii */
- c=buffer[n];
- conout( (ischar(c)) ? (c) : ('.'));
- if (++n==bufend) {
- n=0;
- if (l<(len-16))
- send('\n');
- break;
- }
- }
- }
- return(bfptr);
- }
- void pause(void)
- {
- savecursor();
- print("<more>");
- conin();
- restcursor();
- clreol();
- }
- /*
- * Display sector contents to the screen in HEX/ASCII.
- */
-
- void dumpf(register unsigned char *buffer,int size, int base)
- {
- register int c;
- int i,j;
- int ptr;
-
- send('\n');
- for (ptr=0,i=0;i<size;i+=24)
- {
- pnlz(i,3,base);
- conout(':');
- conout(' ');
- for (j=1;j<=24;j++)
- {
- c=buffer[ptr];
- conout( ((c>>=4) > 9) ? (c+0x57) : (c+'0'));
- c=buffer[ptr];
- conout( ((c&=0xf) > 9) ? (c+0x57) : (c+'0'));
- if (++ptr>=size)
- {
- conout(' ');
- j=9;
- break;
- }
- if (j%8==0)
- conout(' ');
- }
- ptr-=(j-1);
- for (j=1;j<=24;j++)
- {
- c=buffer[ptr];
- conout( (c<' ' || c>0xfe) ? ('.') : (c));
- if (++ptr>=size)
- break;
- }
- }
- }
-